package com.zwd.deep.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.zwd.deep.entity.dto.AppointmentsCheckDTO;
import com.zwd.deep.entity.dto.AppointmentsDTO;
import com.zwd.deep.entity.po.Appointments;
import com.zwd.deep.entity.vo.AppointmentsVo;
import com.zwd.deep.mapper.AppointmentsMapper;
import com.zwd.deep.service.IAppointmentsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 预约时间表 服务实现类
 * </p>
 *
 * @author zwd
 * @since 2025-02-12
 */
@Service
public class AppointmentsServiceImpl extends ServiceImpl<AppointmentsMapper, Appointments> implements IAppointmentsService {
    @Autowired
    private AppointmentsMapper appointmentsMapper;

    @Override
    public List<AppointmentsVo> check(AppointmentsCheckDTO appointmentsCheckDTO) {
        String doctorId = appointmentsCheckDTO.getDoctorId();
        LocalDate startDate = appointmentsCheckDTO.getStartDate();

        // 生成未来七天的日期列表
        List<LocalDate> dateList = generateNextSevenDays(startDate);

        // 定义每天的8个时间段
        List<LocalTime> timeSlots = getLocalTimes();

        // 查询数据库中该医生在未来七天的预约记录
        List<Appointments> appointments = appointmentsMapper.check(doctorId, startDate, startDate.plusDays(6));

        Map<LocalDateTime, List<Appointments>> collect = appointments.stream().collect(Collectors.groupingBy(Appointments::getAppointmentDateTime, Collectors.toList()));
        // 构建响应数据
        List<AppointmentsVo> result = new ArrayList<>();

        // 遍历每个日期和时间段
        for (LocalDate date : dateList) {
            for (LocalTime timeSlot : timeSlots) {
                AppointmentsVo vo = new AppointmentsVo();
                vo.setAppointmentDate(date);
                vo.setAppointmentTime(timeSlot);
                vo.setDoctorId(doctorId);
                vo.setStatus(1);
                LocalDateTime localDateTime = LocalDateTime.of(date, timeSlot);
                List<Appointments> appointmentsList = collect.get(localDateTime);
                if(Objects.nonNull(appointmentsList)){
                    Appointments appointment = appointmentsList.get(0);
                    vo.setStatus(appointment.getStatus() == 2 ? 2 : 1);
                    vo.setUserId(appointment.getUserId());
                }

                result.add(vo);
            }
        }

        return result;
    }

    @NotNull
    private List<LocalTime> getLocalTimes() {
        List<LocalTime> timeSlots = Arrays.asList(
                LocalTime.parse("08:30", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("09:00", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("09:30", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("10:00", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("10:30", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("11:00", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("11:30", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("13:30", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("14:00", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("14:30", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("15:00", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("15:30", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("16:00", DateTimeFormatter.ofPattern("HH:mm")),
                LocalTime.parse("16:30", DateTimeFormatter.ofPattern("HH:mm"))
        );
        return timeSlots;
    }

    @Override
    public void saving(AppointmentsDTO appointmentsDTO) {
        LocalDateTime localDateTime = appointmentsDTO.getAppointmentDate().atTime(appointmentsDTO.getAppointmentTime());
        Appointments is = appointmentsMapper.selectIs(localDateTime, appointmentsDTO.getDoctorId());
        if(Objects.nonNull(is)&& is.getStatus() == 2) {
            throw new RuntimeException("该时间段已被预约");
        }
        Appointments appointments = new Appointments();
        BeanUtil.copyProperties(appointmentsDTO, appointments);
        appointments.setAppointmentDateTime(localDateTime);
        appointments.setStatus(2);
        appointmentsMapper.insert(appointments);
    }

    /**
     * 生成未来七天的日期列表
     *
     * @param startDate 起始日期
     * @return 日期列表
     */
    private List<LocalDate> generateNextSevenDays(LocalDate startDate) {
        List<LocalDate> dates = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            dates.add(startDate.plusDays(i));
        }
        return dates;
    }
}
